﻿using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ZoneLinePacking.Core.EventArgs;
using ZoneLinePacking.Core.Utils;
using ZoneLinePacking.Models.Dto;
using ZoneLinePacking.Models.Entity.BaseInfo;
using ZoneLinePacking.Models.Entity.Template;
using ZoneLinePacking.Models.PrintResult;
using ZoneLinePacking.Models.StationConfig;
using ZoneLinePacking.Services.DB;
using ZoneLinePacking.Services.Message;
using ZoneLinePacking.Services.Print;
using ZoneLinePacking.ViewModelBase;
using ZoneLinePacking.Views.Dialogs;

namespace ZoneLinePacking.ViewModels {

    public class LabelBoxCodePrintViewModel : NavigationViewModel {

        private readonly PrinterBoxCodeService _printerBoxCodeService;
        public LabelBoxCodePrintViewModel(
            IRegionManager regionManager, 
            IDialogService dialog, 
            IMessageService messageBox, 
            IEventAggregator eventAggregator, 
            IDbOperate<IFreeSqlMainContext> dbOperate,
            PrinterBoxCodeService printerBoxCodeService
            ) 
            : base(regionManager, dialog, messageBox, eventAggregator, dbOperate) {

            _printerBoxCodeService = printerBoxCodeService;

        }

        #region Props
        private string _searchText = "";

        public string SearchText {
            get { return _searchText; }
            set { _searchText = value; base.RaisePropertyChanged(); }
        }

        private ObservableCollection<BoxCodePrintResult> _boxCodePrintResults = new ObservableCollection<BoxCodePrintResult>();

        public ObservableCollection<BoxCodePrintResult> BoxCodePrintResults {
            get { return _boxCodePrintResults; }
            set { _boxCodePrintResults = value; base.RaisePropertyChanged(); }
        }

        private ObservableCollection<BoxCodeCompenState> _reBoxCodePrintResults = new ObservableCollection<BoxCodeCompenState>();

        public ObservableCollection<BoxCodeCompenState> ReBoxCodePrintResults {
            get { return _reBoxCodePrintResults; }
            set { _reBoxCodePrintResults = value; base.RaisePropertyChanged(); }
        }

        private BoxCodePrintResult _selectPrintResult;

        public BoxCodePrintResult SelectPrintResult {
            get { return _selectPrintResult; }
            set { _selectPrintResult = value; base.RaisePropertyChanged(); }
        }

        private ObservableCollection<string> _printNames = new ObservableCollection<string>();

        public ObservableCollection<string> PrintNames {
            get { return _printNames; }
            set { _printNames = value; base.RaisePropertyChanged(); }
        }

        private string _selectPrinterName;

        public string SelectPrinterName {
            get { return _selectPrinterName; }
            set { _selectPrinterName = value; base.RaisePropertyChanged(); }
        }
        #endregion

        public DelegateCommand SearchCommand => new DelegateCommand(() => {
            BoxCodePrintResults.Clear();
            ReBoxCodePrintResults.Clear();
            if (string.IsNullOrWhiteSpace(SearchText)) {
                _message.Warning("请输入装箱码！");
                return;
            }

            var list = _mainDbOperate.GetModelList<BoxCodePrintResult>(a => a.BoxCode.Contains(SearchText));
            if (!list.Any()) {
                _message.Info("未查询到当前产品的标签信息！");
                return;
            }

            BoxCodePrintResults.Clear();
            BoxCodePrintResults.AddRange(list);

            var list2 = _mainDbOperate.GetModelList<BoxCodeCompenState>(a => a.BoxCode.Contains(SearchText));
            ReBoxCodePrintResults.Clear();
            ReBoxCodePrintResults.AddRange(list2);
        });

        public DelegateCommand<BoxCodePrintResult> RePrintCommand => new DelegateCommand<BoxCodePrintResult>((rhs) => {
            if (string.IsNullOrEmpty(SelectPrinterName)) {
                _message.Error("请选择打印机！");
                return;
            }
            if (rhs == null) {
                _message.Error("请选择一条打印记录！");
                return;
            }

            bool isAuth = false;
            DialogParameters keyValuePairs = new DialogParameters();
            keyValuePairs.Add("Title", "授权密码");
            _dialog.ShowDialog(nameof(AuthDialogView), keyValuePairs, (dialogRhs) => {
                isAuth = (dialogRhs.Result == ButtonResult.OK);
            });

            //未授权不可走后面的流程
            if (!isAuth) {
                return;
            }

            try {
                var temp = _mainDbOperate.GetModel<TemplateEntity>(o => o.ProductID == rhs.ProductID && o.TemplateType == Enums.eTemplateType.BoxCode);
                if (rhs != null && temp != null) {
                    var dialogAsk = _message.Ask($"确定是否重新打印记录为【{rhs.Id}】的装箱码？");
                    if (dialogAsk == System.Windows.MessageBoxResult.OK) {
                        var dic = JsonConvert.DeserializeObject<Dictionary<string, string>>(rhs.PrintParams);
                        var res = _printerBoxCodeService.RePrintLabel(temp, SelectPrinterName, rhs.BoxCode, dic);
                        if (res) {
                            _message.GrowSuccess("箱码重打成功！");
                            //打印成功，将数据打印的数据记录到关联表中
                            BoxCodeCompenState boxCodeCompenState = JsonConvert.DeserializeObject<BoxCodeCompenState>(JsonConvert.SerializeObject(rhs));
                            boxCodeCompenState.PrintTime = DateTime.Now;
                            boxCodeCompenState.PrintCount = 1;
                            _mainDbOperate.AddModel<BoxCodeCompenState>(boxCodeCompenState);
                        }
                    }
                } else {
                    _message.Error("重打失败，未找到此记录关联的产品！");
                }
            } catch (Exception ex) {
                _message.Error(ex.Message);
            }
        });


        public DelegateCommand<BoxCodePrintResult> BatchRePrintCommand => new DelegateCommand<BoxCodePrintResult>((rhs) => {

            bool isAuth = false;
            DialogParameters dialogParameters = new DialogParameters();
            dialogParameters.Add("Title", "授权密码");
            _dialog.ShowDialog(nameof(AuthDialogView), dialogParameters, (dialogRhs) => {
                isAuth = (dialogRhs.Result == ButtonResult.OK);
            });

            //未授权不可走后面的流程
            if (!isAuth) {
                return;
            }

            if (string.IsNullOrEmpty(SelectPrinterName)) {
                _message.Error("请选择打印机！");
                return;
            }
            if (rhs == null) {
                _message.Error("请选择一条打印记录！");
                return;
            }

            var temp = _mainDbOperate.GetModel<TemplateEntity>(o => o.ProductID == rhs.ProductID && o.TemplateType == Enums.eTemplateType.BoxCode);
            if (temp == null) {
                _message.Error("重打失败，未找到此记录关联的产品模板！");
                return;
            }

            try {
                var dialogAsk = _message.Ask($"确定是否【批量】重新打印记录为【{rhs.Id}】的装箱码？");
                if (dialogAsk != System.Windows.MessageBoxResult.OK) {
                    return;
                }
                
                DialogParameters keyValuePairs = new DialogParameters();
                keyValuePairs.Add("Title", "批量打印数量编辑");
                _dialog.ShowDialog(nameof(BatchPrintDialogView), keyValuePairs, (dialogRes) => {
                    if (dialogRes.Result == ButtonResult.OK) {
                        var printCount = dialogRes.Parameters.GetValue<int>("PrintCount");
                        if (printCount > 0) {
                            var dic = JsonConvert.DeserializeObject<Dictionary<string, string>>(rhs.PrintParams);
                            var res = _printerBoxCodeService.RePrintLabel(temp, SelectPrinterName, rhs.BoxCode, dic, printCount);
                            if (res) {
                                _message.GrowSuccess("箱码重打成功！");
                                //打印成功，将数据打印的数据记录到关联表中
                                BoxCodeCompenState boxCodeCompenState = JsonConvert.DeserializeObject<BoxCodeCompenState>(JsonConvert.SerializeObject(rhs));
                                boxCodeCompenState.PrintTime = DateTime.Now;
                                boxCodeCompenState.PrintCount = printCount;
                                _mainDbOperate.AddModel<BoxCodeCompenState>(boxCodeCompenState);
                            }
                        }
                    }
                });

            } catch (Exception ex) {

                _message.Error(ex.Message);

            }
        });

        public DelegateCommand<string> PrintNewCommand => new DelegateCommand<string>((param) => {

            if (string.IsNullOrEmpty(SelectPrinterName)) {
                _message.Error("请选择打印机！");
                return;
            }


            bool isAuth = false;
            DialogParameters dialogParameters = new DialogParameters();
            dialogParameters.Add("Title", "授权密码");
            _dialog.ShowDialog(nameof(AuthDialogView), dialogParameters, (dialogRhs) => {
                isAuth = (dialogRhs.Result == ButtonResult.OK);
            });

            //未授权不可走后面的流程
            if (!isAuth) {
                return;
            }

            DialogParameters keyValuePairs = new DialogParameters();
            keyValuePairs.Add("Title", "箱码打印");
            _dialog.ShowDialog(nameof(BoxCodePrintDialogView), keyValuePairs, async (rsh) => {
                if (rsh.Result == ButtonResult.OK) {
                    try {

                        var temp = rsh.Parameters.GetValue<TemplateEntity>("TemplateEntity");
                        var dic = rsh.Parameters.GetValue<Dictionary<string, string>>("UserInputParams");
                        var productInfo = _mainDbOperate.GetFreeSql().Select<ProductEntity, CustomerEntity>()
                                     .LeftJoin((a, b) => a.CustomerID == b.Id)
                                     .Where((a, b) => a.Id == temp.ProductID)
                                     .ToList((a, b) => new ProductDto {
                                         ProductName = a.ProductName,
                                         Description = a.Description,
                                         Id = a.Id,
                                         Model = a.Model,
                                         Memo = a.Memo,
                                         WorkDirection = a.WorkDirection,
                                         MaterialNumber = a.MaterialNumber,
                                         Unit = a.Unit,
                                         CustomerID = b.Id,
                                         CustomerName = b.Name,
                                     }).FirstOrDefault();

                        if (param == "Print") {
                            Dictionary<string, string> printParams;
                            string boxNum;
                            var boxCode = _printerBoxCodeService.GenerateQrCode(temp, dic, out boxNum, out printParams, true);
                            await _printerBoxCodeService.PrintLabel(temp.TemplatePath, boxCode, printParams, SelectPrinterName);
                            _message.GrowSuccess($"打印成功！生产的箱码内容是：{boxCode}");
                            //打印成功，将数据打印的数据记录到关联表中
                            var printRecord = new BoxCodePrintResult() {
                                Brand = productInfo.CustomerName,
                                Model = productInfo.Model,
                                BoxCode = boxCode,
                                LeftRight = (int)productInfo.WorkDirection,
                                PrintTime = DateTime.Now,
                                ProductID = productInfo.Id,
                                PrintParams = JsonConvert.SerializeObject(printParams),
                            };
                            _mainDbOperate.AddModel(printRecord);

                        } else if (param == "PrintView") {

                            Dictionary<string, string> printParams;
                            string boxNum;
                            var boxCode = _printerBoxCodeService.GenerateQrCode(temp, dic, out boxNum, out printParams, false);
                            var printRes = _printerBoxCodeService.PrintLabelPreview(temp.TemplatePath, boxCode, printParams, SelectPrinterName);
                            _message.GrowSuccess($"预览成功！生产的箱码内容是：{boxCode}");

                        }

                    } catch (Exception ex) {
                        _message.GrowError(ex.Message);
                        //throw;
                    }
                }
            });


        });

        protected override void OnViewLoaded() {
            var plist = PrinterUtil.GetAllPrinterNames();
            PrintNames.Clear();
            PrintNames.AddRange(plist);
            //base.OnViewLoaded();
            var printConfig = _mainDbOperate.GetModel<PackageScanBarConfig>(p => true);
            SelectPrinterName = printConfig.Printer;
            _eventAggregator.GetEvent<PubSubEventArgs>().Subscribe(OnEventReceived);
        }

        public override void OnNavigatedFrom(NavigationContext navigationContext) {

            _eventAggregator.GetEvent<PubSubEventArgs>().Unsubscribe(OnEventReceived);
            //base.OnNavigatedFrom(navigationContext);
        }


        private void OnEventReceived(MessageData data) {

            if (data.Code == nameof(MainPackingViewModel)) {
                if (data.Parameters.ContainsKey(MainPackingViewModel._scanBarCodeKey)) {
                    string scanBarCode = data.Parameters.GetValue<string>(MainPackingViewModel._scanBarCodeKey);
                    this.SearchText = scanBarCode;
                }
            }

        }

    }
}
